-module(visual).
-compile(export_all).
-include("db.hrl").

-define(VisualReg, java).
-define(VisualName, java).

start() ->
    {ok, Node} = application:get_env(visualNode),

    case Node == undefined of
        true  -> io:format("Visualization OFF\n");
        false -> io:format("Visualization ON; On Node: ~w~n",[Node]),
                 register(?MODULE, spawn(?MODULE, loop, [Node]))
    end.

stop() ->
    case is_started() of
        true  -> ?MODULE ! {stop};
        false -> ok
    end.

visual_chord(State, Path) ->
    case is_started() of
        true  -> ?MODULE ! {visual_chord, State, Path};
        false -> ok
    end.

visual_node(Node, Path) ->
    case is_started() of
        true  -> ?MODULE ! {visual_node, Node, Path};
        false -> ok
    end.

visual_element(Key, Value, Node, Path) ->
    case is_started() of
        true  -> ?MODULE ! {visual_elem, Key, Value, Node, Path};
        false -> ok
    end.


loop(Node) ->
    receive
        {visual_chord, #chord{identity = Id, predecessor = Pred, finger_table = Ft}, Path} ->
            FingerKeys = [ hash:hash(Finger#node.node) || Finger <- Ft ],
            {?VisualReg, Node} ! {chord,{hash:hash(Id#node.node), Id#node.node,
                                       hash:hash(Pred#node.node), FingerKeys}, Path},
            loop(Node);
        {visual_node, Nod, Path} ->
            {?VisualReg, Node} ! {node,{hash:hash(Nod), Nod}, Path},
            loop(Node);
        {visual_elem, Key, Value, Nod, Path} ->
            {?VisualReg, Node} ! {element,{hash:hash(Key), hash:hash(Nod), Key, Value}, Path},
            loop(Node);
        {stop} ->
            ok
    end.

is_started() ->
    case whereis(?MODULE) of
        undefined -> false;
        _         -> true
    end.
